package auth

import (
	"douhu_backend/internal/errors"
	"douhu_backend/internal/infra/logger"
	"douhu_backend/internal/model/auth"
	"time"
)

// PhoneRegisterRequest 手机号注册请求
type PhoneRegisterRequest struct {
	Phone    string `json:"phone" validate:"required"`
	Code     string `json:"code" validate:"required"`
	ClientIP string `json:"client_ip"`
}

// RegisterData 注册成功返回的数据
type RegisterData struct {
	User *auth.User `json:"user"`
}

// PhoneRegister 手机号注册
// 返回 (*RegisterData, error)
// - 成功: 返回 (RegisterData, nil)
// - 失败: 返回 (nil, ServiceError)
func (s *Service) PhoneRegister(req *PhoneRegisterRequest) (*RegisterData, error) {
	// 1. 验证手机号格式
	if !s.validatePhone(req.Phone) {
		return nil, errors.ErrPhoneFormat
	}

	// 2. 获取 DAO 管理器
	daoManager := s.manager.GetDAOManager()
	authDAO := daoManager.Auth

	// 3. 检查用户是否已存在
	existingUser, err := authDAO.GetUserByPhone(req.Phone)
	if err != nil && !authDAO.IsRecordNotFound(err) {
		logger.Errorf("Check user existence failed: %v", err)
		return nil, errors.ErrSystem
	}

	// 如果用户已存在，返回提示
	if existingUser != nil {
		logger.Infof("User already exists: %s", req.Phone)
		return nil, errors.ErrUserAlreadyExists
	}

	// 4. 验证短信验证码（必须是注册类型）
	smsCode, err := authDAO.GetValidSMSCode(req.Phone, auth.SMSCodeTypeRegister)
	if err != nil {
		if authDAO.IsRecordNotFound(err) {
			return nil, errors.ErrCodeNotFound
		}
		logger.Errorf("Get SMS code failed: %v", err)
		return nil, errors.ErrSystem
	}

	// 5. 验证码是否正确
	if smsCode.Code != req.Code {
		logger.Warnf("Invalid code for registration: phone=%s", req.Phone)
		return nil, errors.ErrCodeWrong
	}

	// 6. 标记验证码为已使用
	if err := authDAO.MarkSMSCodeUsed(smsCode.ID, time.Now()); err != nil {
		logger.Errorf("Mark SMS code used failed: %v", err)
		return nil, errors.ErrSystem
	}

	// 7. 创建新用户
	user := &auth.User{
		Phone:         req.Phone,
		Nickname:      "用户" + req.Phone[len(req.Phone)-4:],
		LoginType:     auth.UserLoginTypePhone,
		Status:        auth.UserStatusNormal,
		RegisterIP:    req.ClientIP,
		RegisterTime:  time.Now(),
		LastLoginIP:   req.ClientIP,
		LastLoginTime: time.Now(),
	}

	if err := authDAO.CreateUser(user); err != nil {
		logger.Errorf("Create user failed: %v", err)
		return nil, errors.ErrCreateUserFailed
	}

	logger.Infof("User registered successfully: phone=%s, user_id=%d", req.Phone, user.ID)

	// 返回注册成功数据
	return &RegisterData{
		User: user,
	}, nil
}
